package cn.wizzer.app.web.modules.controllers.platform.bus.equipment;

import cn.wizzer.app.bus.modules.models.equipment.BusEquipment;
import cn.wizzer.app.bus.modules.models.equipment.BusEquipmentInspection;
import cn.wizzer.app.bus.modules.models.equipment.BusEquipmentInspectionInventory;
import cn.wizzer.app.bus.modules.models.equipment.BusEquipmentProcess;
import cn.wizzer.app.bus.modules.services.*;
import cn.wizzer.app.sys.modules.services.SysDictService;
import cn.wizzer.app.sys.modules.services.SysUnitService;
import cn.wizzer.app.sys.modules.services.SysUserService;
import cn.wizzer.app.web.commons.slog.annotation.SLog;
import cn.wizzer.app.web.commons.utils.ShiroUtil;
import cn.wizzer.app.web.commons.utils.StringUtil;
import cn.wizzer.framework.base.Result;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.integration.json4excel.J4E;
import org.nutz.integration.json4excel.J4EColumn;
import org.nutz.integration.json4excel.J4EConf;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author tcjinxiu.com
 * @time 2024-04-11 10:19:44
 *
 */
@IocBean
@At("/platform/bus/equipment/inspection_back")
public class BusEquipmentInspectionController_back {
private static final Log log = Logs.get();
	@Inject
	BusEquipmentInspectionService busEquipmentInspectionService;

	@Inject
	BusEquipmentInspectionInventoryService busEquipmentInspectionInventoryService;
	@Inject
	BusEquipmentCheckService busEquipmentCheckService;
	@Inject
	BusEquipmentService busEquipmentService;
	@Inject
	BusEquipmentProcessService busEquipmentProcessService;
	@Inject
	private SysDictService sysDictService;
	@Inject
	private SysUnitService sysUnitService;
	@Inject
	private SysUserService sysUserService;
	@Inject
	private ShiroUtil shiroUtil;

	private static final String type="inspection";
	@At("/?")
	@Ok("beetl:/platform/bus/equipment/inspection/index.html")
	@RequiresAuthentication
	public void index(String processName,HttpServletRequest req) {
		req.setAttribute("userId",StringUtil.getPlatformUid());
		req.setAttribute("processName", processName);
		req.setAttribute("processMap", JSONObject.fromObject(sysDictService.getCodeMap("equipmentProcessCode")));
		List<NutMap> list = sysDictService.dictCodeTree("equipmentProcessCode");
		list.remove(2);
		list.remove(2);
		list.remove(2);
		req.setAttribute("processOptions", JSONArray.fromObject(list));
		req.setAttribute("calculateMap", JSONObject.fromObject(sysDictService.getCodeMap("calculate")));
		req.setAttribute("calculateCycleTypeMap", JSONObject.fromObject(sysDictService.getCodeMap("calculateCycleType")));
	}

	@At
	@Ok("json:full")
	@RequiresAuthentication
	public Object data(@Param("code") String code, @Param("name") String name,@Param("lczt") String lczt,@Param("status") String status,
					   @Param("processName") String processName,
					   @Param("pageNumber") int pageNumber,@Param("pageSize") int pageSize
			, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
		try {
			String sql = "select * from (select urr.username as opName,FROM_UNIXTIME(es.opAt) as opTime,  " +
					" es.id,es.lczt,es.nextspr,es.measurementUnit,es.outMeBy,es.outAt,es.inAt,es.inMeBy,es.outRemark,es.inRemark,es.calculateDate,es.opBy," +
					" (select count(1) from bus_equipment_inspection_inventory where inspectionId = es.id) as equipmentCount " +
					" from bus_equipment_inspection es  " +
					" left join sys_user urr on urr.id=es.opBy   " +
					" where es.delFlag=0 ";
			if(StringUtils.isNotBlank(processName)&& processName.equals("audit")){
				sql+= " and es.nextsprIds='"+StringUtil.getPlatformUid()+"' and (es.lczt = 2 or es.lczt = 1)";
			}else if (StringUtils.isNotBlank(processName)&& processName.equals("complete")){
				sql+=  " and es.opBy = '"+StringUtil.getPlatformUid()+"'";
				if(StringUtils.isNotBlank(status)){
					sql+= " and  es.lczt = '"+status+"' ";
				}else{

					sql+= " and  (es.lczt = 1 or es.lczt = 5)  ";
				}
			}else{
				//数据权限
				sql+= StringUtil.dataScopeFilter("es");
			}
			if(StringUtils.isNotBlank(code)){
				sql+= " and  es.id in (select inspectionId from bus_equipment_inspection_inventory eii " +
						"left join bus_equipment e on e.id = eii.equipmentId where e.code like '%"+code+"%')  ";
			}
			if(StringUtils.isNotBlank(name)){
				sql+= " and  es.id in (select inspectionId from bus_equipment_inspection_inventory eii " +
						"left join bus_equipment e on e.id = eii.equipmentId where e.name like '%"+name+"%')  ";
			}
			if(StringUtils.isNotBlank(lczt)){
				sql+= " and  es.lczt = '"+lczt+"' ";
			}
			sql+= " ) a  ";
			if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
				if ("ascending".equalsIgnoreCase(pageOrderBy)) {
					sql+= " order by "+pageOrderName+" asc,opTime desc ";
				} else {
					sql+= " order by "+pageOrderName+" desc,opTime desc ";
				}
			}else{
				sql+= " order by opTime desc ";
			}
			return Result.success().addData(busEquipmentInspectionService.listPage(pageNumber, pageSize, Sqls.create(sql)));
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error();
		}
	}


	@At
	@Ok("json:full")
	@RequiresAuthentication
	public Object equipmentData(@Param("equipmentId") String equipmentId,
					   @Param("pageNumber") int pageNumber,@Param("pageSize") int pageSize) {
		try {
			String sql = "select  es.id,es.measurementUnit,es.outMeBy,es.outAt,es.inAt,es.inMeBy,es.outRemark,es.inRemark,es.calculateDate,es.opBy" +
					" from bus_equipment_inspection es  " +
					" left join bus_equipment_inspection_inventory eii on eii.inspectionId=es.id   " +
					" where es.delFlag=0 and es.lczt = 5 ";

			if(StringUtils.isNotBlank(equipmentId)){
				sql+= " and  eii.equipmentId = '"+equipmentId+"' ";
			}
			sql+= " order by es.opAt desc ";
			return Result.success().addData(busEquipmentInspectionService.listPageMap(pageNumber, pageSize, Sqls.create(sql)));
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error();
		}
	}

	@Aop(TransAop.READ_COMMITTED)
	@At
	@Ok("json")
	@RequiresPermissions("equipment.inspection.add")
	@SLog(tag = "Add", msg = "Add:bus_equipment_inspection")
	public Object addDo(@Param("inspection") BusEquipmentInspection inspection,HttpServletRequest req) {
		try {
			inspection.setOpBy(StringUtil.getPlatformUid());
			inspection.setOpAt(Times.getTS());
			inspection.setDelFlag(false);
			String equipmentIds = "";
			if(inspection.getInventorys() != null && inspection.getInventorys().size()>0){
				inspection.getInventorys().stream().map(t -> {
					t.setOpAt(Times.getTS());
					t.setOpBy(StringUtil.getPlatformUid());
					t.setDelFlag(false);
				return t;
				}).collect(Collectors.toList());
				equipmentIds = "'"+inspection.getInventorys().stream().map(t -> t.getEquipmentId()).collect(Collectors.joining("','"))+"'";
			}
			inspection = busEquipmentInspectionService.insertWith(inspection, "inventorys");
			BusEquipmentProcess process = new BusEquipmentProcess();
			process.setHeadId(inspection.getId());
			//process.setEquipmentId(inspection.getEquipmentId());
			process.setLczt(inspection.getLczt());
			process.setType(type);
			process.setStatus("0");
			process.setNextspr(inspection.getNextspr());
			process.setNextsprIds(inspection.getNextsprIds());
			if (StringUtils.isNotBlank(equipmentIds)&&inspection.getLczt().equals("1")) {
				busEquipmentService.execute(Sqls.create(" update bus_equipment set status='3' where id in(" + equipmentIds + ")"));
			}
			busEquipmentProcessService.insert(process);
			busEquipmentInspectionService.clearCache();
			return Result.success("system.success");
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("system.error");
		}
	}
	@At("/detail/?")
	@Ok("json")
	public Object detail(String id) {
		BusEquipmentInspection inspection = busEquipmentInspectionService.fetchLinks(busEquipmentInspectionService.fetch(id),"inventorys");
		List listProcess = busEquipmentProcessService.list(Sqls.create("select *,(select username from sys_user where id = es.opBy) as opName,FROM_UNIXTIME(es.opAt) as opTime from  bus_equipment_process es where " +
				" headId='" + inspection.getId() + "' and type='" + type + "' order by opAt desc"));
		NutMap map = new NutMap();
		for(BusEquipmentInspectionInventory inventory: inspection.getInventorys()){
			BusEquipment e= busEquipmentService.fetch(inventory.getEquipmentId());
			inventory.setEquipmentName(e.getName());
			inventory.setEquipmentCode(e.getCode());
		}
		map.addv("inspection", inspection);
		map.addv("listProcess", listProcess);
		try {
			return Result.success("system.success").addData(map);
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}

	@Aop(TransAop.READ_COMMITTED)
	@At
	@Ok("json")
	@RequiresPermissions("equipment.inspection.edit")
	@SLog(tag = "Edit", msg = "Edit:bus_equipment_inspection")
	public Object editDo(@Param("inspection") BusEquipmentInspection inspection, HttpServletRequest req) {
		try {
			String equipmentIds = "";
			if(inspection.getInventorys() != null && inspection.getInventorys().size()>0){
				equipmentIds = "'"+inspection.getInventorys().stream().map(t -> t.getEquipmentId()).collect(Collectors.joining("','"))+"'";
				for (BusEquipmentInspectionInventory item : inspection.getInventorys()) {
					item.setInspectionId(inspection.getId());
					item.setOpAt(Times.getTS());
					item.setOpBy(StringUtil.getPlatformUid());
					item.setDelFlag(false);
					busEquipmentInspectionInventoryService.insertOrUpdate(item);
				}
			}
			BusEquipmentProcess process = new BusEquipmentProcess();
			process.setHeadId(inspection.getId());
			//process.setEquipmentId(servicing.getEquipmentId());
			process.setLczt(inspection.getLczt());
			process.setType(type);
			process.setStatus("0");
			process.setNextspr(inspection.getNextspr());
			process.setNextsprIds(inspection.getNextsprIds());
			if (StringUtils.isNotBlank(equipmentIds)&&inspection.getLczt().equals("1")) {
				busEquipmentService.execute(Sqls.create(" update bus_equipment set status='3' where id in(" + equipmentIds + ")"));
			}
			busEquipmentInspectionService.update(inspection);
			busEquipmentProcessService.execute(Sqls.create("update bus_equipment_process set delflag=1 where lczt>=" + inspection.getLczt() + " and headId='" + inspection.getId() + "' and type='" + type + "' "));
			busEquipmentProcessService.insert(process);
			busEquipmentInspectionService.clearCache();
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}


	@Aop(TransAop.READ_COMMITTED)
	@At("/subDo/?")
	@Ok("json")
	@RequiresPermissions("equipment.inspection.edit")
	@SLog(tag = "subDo", msg = "subDo:bus_equipment_inspection")
	public Object subDo(String id) {
		try {
			BusEquipmentInspection inspection = busEquipmentInspectionService.fetchLinks(busEquipmentInspectionService.fetch(id),"inspectionId");
			inspection.setLczt("1");
			BusEquipmentProcess process = busEquipmentProcessService.fetch(Cnd.NEW().and("headId", "=", inspection.getId())
					.and("lczt","=","0").and("delflag","=","0").and("type", "=", type));
			process.setHeadId(inspection.getId());
			process.setLczt(inspection.getLczt());
			process.setType(type);
			process.setStatus("0");
			String equipmentIds = "";
			if(inspection.getInventorys() != null && inspection.getInventorys().size()>0){
				equipmentIds = "'"+inspection.getInventorys().stream().map(t -> t.getEquipmentId()).collect(Collectors.joining("','"))+"'";
			}
			if(StringUtils.isNotBlank(equipmentIds)){
				busEquipmentService.execute(Sqls.create(" update bus_equipment set status='3' where id in("+ equipmentIds +")"));
			}
			busEquipmentInspectionService.update(inspection);
			busEquipmentProcessService.execute(Sqls.create("update bus_equipment_process set delflag=1 where lczt>=" + inspection.getLczt() + " and headId='" + inspection.getId() + "' and type='"+type+"' "));
			busEquipmentProcessService.insert(process);
			busEquipmentInspectionService.clearCache();
			return Result.success("system.success");
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("system.error");
		}
	}


	@Aop(TransAop.READ_COMMITTED)
	@At
	@Ok("json")
	@SLog(tag = "processDo", msg = "processDo:bus_equipment_inspection")
	public Object processDo(@Param("inspection") BusEquipmentInspection inspection,@Param("..") BusEquipmentProcess process,
							HttpServletRequest req) {
		try {
			String jlrq = inspection.getCalculateDate();
			inspection.setAuditFlag("1");
			inspection.setLczt("5");
			process.setHeadId(inspection.getId());
			//process.setEquipmentId(inspection.getEquipmentId());
			process.setLczt(inspection.getLczt());
			process.setType(type);
			process.setOpBy(StringUtil.getPlatformUid());
			process.setOpAt(Times.getTS());
			String equipmentIds = "";
			if(inspection.getLczt().equals("5")){
				//最后完成后设备状态恢复正常
				if(inspection.getInventorys() != null && inspection.getInventorys().size()>0){
					equipmentIds = "'"+inspection.getInventorys().stream().map(t -> t.getEquipmentId()).collect(Collectors.joining("','"))+"'";
					for (BusEquipmentInspectionInventory item : inspection.getInventorys()) {
						busEquipmentInspectionInventoryService.insertOrUpdate(item);
					}
				}
			}
			if(StringUtils.isNotBlank(equipmentIds)){
				busEquipmentService.execute(Sqls.create(" update bus_equipment set status='1',calculateUnit='"+inspection.getMeasurementUnit()+"' where id in("+ equipmentIds +")"));
				busEquipmentService.execute(Sqls.create(" update bus_equipment set calculateDate=case " +
						"when calculateCycleType = 'year' then DATE_ADD('"+jlrq+"', INTERVAL calculateCycle YEAR) " +
						"when calculateCycleType = 'month' then DATE_ADD('"+jlrq+"', INTERVAL calculateCycle MONTH) " +
						"when calculateCycleType = 'day' then DATE_ADD('"+jlrq+"', INTERVAL calculateCycle DAY) " +
						"else calculateDate end where  calculateDate is not null and calculateDate !='' and id in("+ equipmentIds +")"));
			}
			busEquipmentInspectionService.update(inspection);
			busEquipmentProcessService.insert(process);
			busEquipmentInspectionService.clearCache();
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}


	@At({"/delete","/delete/?"})
	@Ok("json")
	@RequiresPermissions("equipment.inspection.delete")
	@SLog(tag = "Delete", msg = "Delete:bus_equipment_inspection")
	public Object delete(String id,@Param("ids") String[] ids, HttpServletRequest req) {
		try {
			if(ids!=null&&ids.length>0){
				busEquipmentInspectionService.vDelete(ids);
			}else{
				busEquipmentInspectionService.vDelete(id);
			}
			busEquipmentInspectionService.clearCache();
			return Result.success("system.success");
		} catch (Exception e) {
			return Result.error("system.error");
		}
	}
	@At
	@Ok("void")
	public void export(@Param("id") String id, HttpServletResponse response) {
		try {
			BusEquipmentInspection inspection = busEquipmentInspectionService.fetch(id);
			String sql = " select e.*,ur.username as managerName,ut.name as applyName " +
					" from bus_equipment e  " +
					" left join sys_user ur on ur.id=e.managerBy " +
					" left join sys_unit ut on ut.id = e.applyDept  "+
					" left join bus_equipment_inspection_inventory eii on eii.equipmentId = e.id where e.delFlag=0 ";
			if(StringUtils.isNotBlank(id)){
				sql+= " and  eii.inspectionId = '"+id+"' ";
			}
			sql+= " order by e.code asc ";

			List<BusEquipment> listObj = busEquipmentService.listEntity(Sqls.create(sql));


			Map statusMap = sysDictService.getCodeMap("equipmentStatus");
			Map calculateMa=sysDictService.getCodeMap("calculate");
			Map calculateCycleTypeMap=sysDictService.getCodeMap("calculateCycleType");
			listObj.stream().map(obj -> {
				if(StringUtils.isNotBlank(obj.getStatus())){
					obj.setStatus(StringUtil.getDict(obj.getStatus(),statusMap));
				}
				if(StringUtils.isNotBlank(obj.getCalculate())){
					obj.setCalculate(StringUtil.getDict(obj.getCalculate(),calculateMa));
				}
				if(StringUtils.isNotBlank(obj.getCalculateCycleType())){
					obj.setCalculateCycleType(StringUtil.getDict(obj.getCalculateCycleType(),calculateCycleTypeMap));
				}
				if(StringUtils.isNotBlank(obj.getImportedFlag())){
					if(obj.getImportedFlag().equals("0")){
						obj.setImportedFlag("是");
					}else{
						obj.setImportedFlag("否");
					}
				}
				obj.setManagerBy(obj.getManagerName());
				obj.setApplyDept(obj.getApplyName());
				return obj;
			}).collect(Collectors.toList());

			J4EConf j4eConf = J4EConf.from(BusEquipment.class);
			List<J4EColumn> jcols = j4eConf.getColumns();
			for (J4EColumn j4eColumn : jcols) {
				if ("opBy".equals(j4eColumn.getFieldName()) || "opAt".equals(j4eColumn.getFieldName()) || "delFlag".equals(j4eColumn.getFieldName())) {
					j4eColumn.setIgnore(true);
				}
			}
			j4eConf.setSheetName("送检设备清单"+ inspection.getOutAt().substring(0,10));
			OutputStream out = response.getOutputStream();
			response.setHeader("content-type", "application/shlnd.ms-excel;charset=utf-8");
			response.setHeader("content-disposition", "attachment; filename=" + new String(j4eConf.getSheetName().getBytes(), "ISO-8859-1") + ".xls");
			J4E.toExcel(out, listObj, j4eConf);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}
}
